#pragma once

#include "BasicObject.h"
#include "event.h"
#include "role.h"
#include "agent.h"

#include "world.h"
#include "typdefs.h"
#include "action.h"


#include "emotionalmemory.h"

#include <string>
#include <vector>
#include <map>


namespace BAA
{

	class Agent;
	typedef std::vector< Agent*>											AgentVector;
	class Role;
	class Value;
	class EmotionalMemory;
	class Event;
	class Action;
	//////////////////////////////////////////////////////////////////////////
	// Value Maps
	//////////////////////////////////////////////////////////////////////////
	typedef std::map<Value*, Value*, std::less<Value*>>				ValueValueMap;
	typedef std::map<std::string, std::vector<Value*>, std::less<std::string>>		StringValuesMap;
	typedef std::map<Agent*, std::vector<Value*>*, std::less<Agent*>>	AgentValuesMap;

	class Value:public BasicObject
	{
	public:
		Value(const std::string name):BasicObject(name)
		{

		}

		~Value()
		{

		}

		void Create();

		void Initialize(Role * parent)
		{
			mRoleParent = parent;
		}

		void Clear();



		virtual EmotionalMemory* AppraiseEvent(Event * event)=0;
		virtual float CalculateImportance(Agent * self)=0;
		virtual float CalculateUtility(Action *action)=0;

		virtual void AddConsequenceWatch(std::string name, float value)
		{
			mStringFloatData[name] = value;
		}

	/*	virtual void AddTargetWatch(Agent * agent)
		{
			mTargets->push_back(agent);
		}*/


		Role * RoleParent() { return mRoleParent; }
		void RoleParent(Role * val) { mRoleParent = val; }

		StringFloatMap* Consequences() { return &mStringFloatData; }
		//const StringFloatMap* Consequences() const { return mStringFloatData; }
		
		void Consequences(StringFloatMap  val) { mStringFloatData = val; }

		Role * ParentRole() const { return mRoleParent; }
		void ParentRole(Role * val) { mRoleParent = val; }

		bool WatchTargets() const { return mWatchTargets; }
		void WatchTargets(bool val) { mWatchTargets = val; }

		bool WatchConsequences() const { return mWatchConsequences; }
		void WatchConsequences(bool val) { mWatchConsequences = val; }

		//AgentVector * Targets() const { return mTargets; }
		//void Targets(AgentVector * val) { mTargets = val; }
		

	protected:


		// Role associated with this value
		Role * mRoleParent;

		// any target the value is concerned with. 
		//AgentVector * mTargets;

		// a list of properties associated via strings and floats 
		// updated as needed.

		StringFloatMap	mStringFloatData;

		bool mWatchConsequences;

		bool mWatchTargets;






	};// end class
}// end namespace
